Utilisation de méthodes synthétiques de haut niveau

Cette rubrique sert à illustrer la manière d'utiliser certaines fonctionnalités clés des méthodes synthétiques de haut niveau. Pour plus d'informations, consulter la documentation Javadoc™ relative aux méthodes et classes API Framework for Frameworks.

Création d'une méthode synthétique de haut niveau

Pour créer une méthode synthétique de haut niveau et l'ajouter à l'objet F4FActions actions, utilisez les codes suivants :

HighLevelSyntheticMethod m = HighLevelSyntheticMethod.make();
actions.addHighLevelSyntheticMethod(m);

Vous pouvez spécifier le nom, les types de paramètre et le type de retour de la méthode synthétique en transmettant une signature de méthode VDB à HighLevelSyntheticMethod.make().

Création de variables locales

Il est possible de créer une variable locale pour une méthode synthétique de haut niveau m en procédant comme suit :

Local l = m.newLocal("java.lang.String");

Il n'est pas nécessaire d'appeler des constructeurs dans des méthodes synthétiques. Lorsque l'on utilise le code précédemment indiqué, on peut supposer que l fait référence à un objet String non nul lors de l'ajout d'instructions supplémentaires à la méthode synthétique.

Ajout d'appels

La plupart des instructions figurant dans les méthodes synthétiques de haut niveau sont des appels de méthode ajoutés via la méthode addCall(). Les paramètres de addCall() représentent la méthode à appeler, les informations d'emplacement de fichier pour l'appel et les paramètres à transmettre lors de l'appel. Voici un exemple d'ajout d'un appel à une méthode d'accès set sample.BeanType.setName(), en prenant un objet F4FApp app :

Collection<IMethod> setterMethods =
   app.getClassMethods("sample.BeanType", "setName");
// assume there is exactly one "setName" method in BeanType
IMethod setter = setterMethods.iterator().next();
HighLevelSyntheticMethod m = HighLevelSyntheticMethod.make();
Local l = m.newLocal("sample.BeanType");
m.addCall(setter, null, l, Taint.taint());

Les étapes 2 à 5 de la gestion de la soumission du formulaire client dans une architecture MVC (comme indiqué dans Méthodes synthétiques de haut niveau) peuvent toutes faire l'objet d'un certain degré de modélisation en ajoutant des appels appropriés à une méthode synthétique de la façon mentionnée précédemment.

Les paramètres d'un appel sont représentés par les objets de type Param, qui peuvent être l'un des suivants :

  • Objet Local, représentant une variable locale
  • Objet Taint, représentant des données non sûres ou tâchées.
  • Objet EnclosingFormal, représentant un paramètre formel de la méthode synthétique de haut niveau. Par exemple, si vous disposez d'une méthode synthétique avec la signature synthMethod(int):void, EnclosingFormal.FIRST fait référence au paramètre int de la méthode.
  • Objet Global représentant des données globales (présenté dans Objets Global).
Remarque : Pour les méthodes d'instance non statiques, la valeur à transmettre sous la forme this doit être fournie à addCall(). Dans l'exemple fourni précédemment, la valeur dans l est transmise sous la forme this à setName().

Ajout d'une valeur de retour

Une méthode synthétique peut renvoyer une valeur à l'aide de la méthode setReturnedValue(). Les valeurs de retour peuvent être utiles pour générer des méthodes de marqueur permettant de modéliser une validation de cadre complexe. Par exemple, si vous utilisez une structure qui effectue la validation complexe d'une requête HTTP contaminée avant de la transmettre à la méthode d'accès set d'un objet de modèle, vous pouvez exposer la validation sur les traces découvertes par AppScan® Source en utilisant un code similaire au suivant :

String validatorSig =
   "Synth.validatorModel(java.lang.String):
   java.lang.String";
HighLevelSyntheticMethod validator =
   HighLevelSyntheticMethod.make(validatorSig);
// just return the parameter passed in
validator.setReturnedValue(EnclosingFormal.FIRST);
HighLevelSyntheticMethod m = ...;
Local validated = m.addCall(validatorSig, null, Taint.taint());
// now, validated can be passed to a setter

La méthode synthétique Synth.validatorModel() renvoie simplement la chaîne String qui lui est transmise en tant que paramètre. Ensuite, un appel à Synth.validatorModel() est ajouté à une autre méthode synthétique, transmettant ainsi une valeur contaminée en tant qu'argument. Le résultat de cet appel est stocké dans validated, qui peut être transmis dans un appel ultérieur à une méthode d'accès set (comme illustré par l'exemple figurant dans Ajout d'appels). Les traces impliquant ces données contaminées incluent l'appel à Synth.validatorModel() et un utilisateur AppScan Source peut choisir de filtrer les traces si la validation est jugée suffisante.

Objets Global

Les objets Global sont des fonctions avancées qui permettent d'exposer un flux entre les différentes parties d'une application. Par exemple, les objets Global peuvent servir à modéliser le flot de données depuis un contrôleur vers une vue via une demande ou des attributs de session. Les principales opérations permettant de créer et d'accéder à des objets Global sont les suivantes :

  • Pour créer un objet Global représentant des données globales, utilisez F4FActions.createGlobal().
  • Pour écrire dans un objet Global, utilisez HighLevelSyntheticMethod.addGlobalWrite().
  • Pour lire un objet Global, transmettez l'objet Global sous forme de paramètre Param dans un appel envoyé à HighLevelSyntheticMethod.addCall() ou faites en sorte qu'il soit renvoyé par une méthode synthétique via HighLevelSyntheticMethod.setReturnedValue().

Exemple : une classe de contrôleur écrit le prénom d'un utilisateur dans l'attribut de demande firstName, puis la vue lit cet attribut de demande et renvoie la valeur dans la réponse. A haut niveau, il est possible de modéliser ce flot comme suit :

Global firstNameGlobal = actions.createGlobal
   ("firstName", "java.lang.String", true);
HighLevelSyntheticMethod controller = ...;
Local firstNameLocal = controller.newLocal("java.lang.String");
controller.addGlobalWrite(firstNameGlobal, firstNameLocal, null);
HighLevelSyntheticMethod view = ...;
view.addCall("Response.write(java.lang.String):void",
   null, firstNameGlobal);

En ajoutant une écriture dans firstNameGlobal dans la méthode synthétique du contrôleur, puis en transmettant firstNameGlobal à Response.write() dans la méthode synthétique view, le flux de données allant du contrôleur vers la vue est exposé.

Remarque : Cet exemple contient de nombreuses simplifications. Une version complète devrait exposer le flux de données approprié à firstNameLocal.