"expecting leftbrace before dotlessthan"

23/05/2008 Aucun commentaire

Adobe a publié la semaine passée une première beta du Player Flash 10 (nom de code : Astro), implémentant une mise à jour de l’API de dessin, Hydra et quelques modifications de langages, dont le type Vector.

Je ne reviendrais pas dessus, car c’est un sujet qui a été largement couvert par de nombreux blogs, voici simplement quelques liens :

J’esperais plus des modifications de langage apportées par Astro. Si l’implémentation du proposal:Vector est une excellente chose, l’absence de nombreux éléments des drafts ECMA4 fait mal.

Et là où je déplore le manque, c’est surtout sur l’impossibilité de déclarer des classes génériques personnalisées :

package {
    public class CustomGeneric.
    {
    }
}

Et bim: 1084: Syntax error: expecting leftbrace before dotlessthan.

En lisant la discussion sur les paramètres-types, je m’attendais à pouvoir faire ça de mon côté. Et visiblement non. Dommage… Une prochaine fois? Après tout, ce n’est qu’une première beta.

Allez, salut.

Categories: Code Tags: ,

Les SWC produits par Flex Builder contiennent un SWF étrange.

12/04/2008 un commentaire

Je bosse actuellement sur un système de tests unitaires en AS3, car FlexUnit ne me convenait pas par la lourdeur (certainement subjective) de son utilisation. Le principe de base consiste à compiler le projet de tests unitaires sous forme d’un SWC, qui est ensuite chargé et décompressé par le système, qui en extrait le SWF de librairies afin de le charger, pour pouvoir exécuter le code des classes de tests.

Tout marche vachement bien, et hier soir, je me dis que je vais le ramener à la maison pour trifouiller un peu ce week-end. Et là, crack, impossible de le faire marcher de chez moi. Wtf? En fait, lorsque le SWF est chargé par un Loader, ce dernier ne produit pas d’évènement INIT, ni d’évènement COMPLETE. Il produit par contre des évènements PROGRESS, dont un où bytesLoaded == bytesTotal. Mais les classes contenues par le SWF ne sont (visiblement) jamais ajoutées à l’ApplicationDomain précisé dans le LoaderContext.

Après une petite analyse, il apparait que les SWC produits par FlexBuilder ne sont pas strictement identiques à un SWC produit par compc. À coup de Swfmill, la différence apparaît clairement:

SWF contenu dans un SWC produit par compc, exemple de contenu pour le tag 0×52 (ABC pour AVM2), en Base64 :

AAAAAFVuaXRUZXN0aW5nQ29t(...)

SWF contenu dans un SWC produit par FlexBuilder, même segment du même tag, en Base64 :

AQAAAFVuaXRUZXN0aW5nQ29t(...)

Ne me demandez pas ce que fout ce Q là, mais en le remplaçant par un A, le SWF fonctionne à nouveau. Si une personne connaissant mieux le bytecode AVM2 que moi (ce qui n’est pas difficile), et ayant une idée de ce que signifie ces entêtes, toute info est la bienvenue. Allez, salut.

Categories: Code Tags: ,

Récupérer un Loader depuis un callback de type IOErrorEvent…

25/02/2008 3 commentaires

Tout le monde aura déjà écrit un code de ce genre :

var ldr : Loader = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
ldr.load(new URLRequest("http://www.bidon.com/trucmuche.jpg"));

Ca marche bien. Mais il se trouve que dans mon projet, on a tendance à avoir besoin de beaucoup, beaucoup de loaders. Je me suis donc dit « Allons, Tyn, utilise donc un pool ! » Ce qui marche également bien. On a un gain de plus de 1000% en utilisant un pool de Loader plutôt que d’en créer de nouveaux à chaque fois.

Mais qui dit pool dit nettoyage d’objet, et rendu dudit objet au pool après son utilisation. Hors, dans ce cas précis, j’ai un gros soucis: je ne peux pas récupérer mon objet Loader dans mon callback onIOError! C’est quand même très, très con. Ca signifie que je perds un élément de mon pool à chaque URL foireuse, ce qui est un leak inacceptable.

Voici donc un contournement foireux pour récupérer son objet Loader depuis un callback où LoaderInfo.loader n’est pas encore renseigné:

package net.tynambule.exp {
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;
	public class IOErrorCallbackWithLoader extends Sprite
	{
		private var _loaders : Dictionary = new Dictionary(true);
		public function IOErrorCallbackWithLoader()
		{
			var ldr : Loader = new Loader();
			ldr.contentLoaderInfo.addEventListener(Event.INIT, onInit);
			ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			// Feinte ici :
			_loaders[ldr.contentLoaderInfo] = ldr;
			ldr.load(new URLRequest("existe-po.png"));
		}
		private function onInit(e : Event) : void
		{
			trace("Trop bien, le fichier existait!");
			// Ne pas oublier d'effacer ma référence, histoire que mon Loader puisse
			// être garbage collecté.
			delete _loaders[e.target];
		}
		private function onIOError(ioe : IOErrorEvent) : void
		{
			trace("Le fichier existait pas, mais j'ai toujours mon loader!");
			trace("Le voici :" + _loaders[ioe.target]);
			// Ne pas oublier d'effacer ma référence, histoire que mon Loader puisse
			// être garbage collecté.
			delete _loaders[ioe.target];
		}
	} }

Et hop. C’est quand même bien crade. Si un gentil développeur de chez Adobe passe par ici (sait-on jamais), c’est quand même con que le Loader ne soit pas accessible depuis l’objet LoaderInfo en cas d’erreur de chargement alors qu’il est disponible avant le chargement. Allez, salut.

Categories: Code Tags: ,

Problématique de sandboxing d’un SWF untrusted chargé dans un SWF trusted

21/02/2008 un commentaire

Wouah, quel titre à rallonge. J’ai posté aujourd’hui un petit message sur Mediabox sur une question qui me parait sans réponse (satisfaisante) pour l’instant, et je la mets ici aussi histoire de poster un peu, pasque ces temps-ci, je m’oublie un peu sur ce blog. ^^

Salut les gens,

J’ai une question assez pointue sur la gestion de la sécurité par le Player Flash, avec un peu de bol quelqu’un se sera déjà cogné les dents là dedans. ^^

Voici mon soucis. J’ai deux fichiers SWF executés depuis une installation locale dans un dossier listé dans le répertoire FlashPlayerTrust: le « maître » et un « esclave ». Le « maître » est executé par l’utilisateur. Lors de l’execution de ce dernier, j’aimerais pouvoir charger mon SWF « esclave » et executer du code AS3 placé à l’interieur.

Mais voilà la petite difficulté: le fichier SWF « maître » est une application de confiance (vu que c’est moi qui la code). Les utilisateurs ne peuvent pas la modifier (enfin, ce n’est pas le débat). Elle communique via un Socket avec un serveur distant, et accède à certains fichiers en local ainsi que sur le Web. Jusque là, pas de soucis.

Seulement, mon SWF « esclave », ce n’est pas moi qui le code, c’est des utilisateurs tiers qui n’ont pas toute ma confiance. J’aimerais laisser le code AS dans les SWF « esclave » accéder à certaines parties bien définies d’une API pour permettre la personnalisation de mon application « maître ». Pour cette partie, pas de soucis.

Mais là où ça se corse, c’est que je ne veux pas que les SWF « esclave » produit par des tiers puissent constituer des chevaux de troies. En clair, je ne veux pas qu’ils puissent communiquer avec l’extérieur, via un socket ou des appels à une page http distante.

Il n’y a à ma connaissance pas de moyen de charger un SWF dans une sandbox particulière, je ne peux donc pas bloquer mes SWF « esclave » dans une sandbox Local-with-file.

Je vois deux solutions possibles :

* Ne pas utiliser des SWF avec de l’actionscript. Créer un pseudolangage, et le parser/executer depuis mon SWF « maître ». Ca peut marcher, mais c’est long, pénible et source de bugs, pouvant même ouvrir des failles de sécurité.

* Charger le SWF « esclave » deux fois: une première fois en tant que donnée binaire, pour parser le format de fichier swf et récupérer les tags de bytecode, puis pour parser ce bytecode à la recherche d’appel à l’API Flash bloqués (l’utilisation d’une classe socket, ce genre de trucs). Mais là, le soucis, c’est que si Adobe change une virgule dans son code et modifie d’un poil le bytecode, paf, une faille. Pareil, si un méchant codeur tiers modifie son swf de façon à ce que la signature de sa classe socket soit légèrement différente, mais qu’elle continue à fonctionner pour le player (en admettant que ce soit possible), paf, feinté. Et en plus, c’est long et compliqué à développer.

Donc voilà, ça me parait être un problème insoluble mais sait-on jamais. Avez-vous une idée meilleure que les miennes? ^^

Merci d’avance!

Alors, fidèle lecteur, as-tu une solution? Allez, salut.

Categories: Code Tags:

La machine à pain

26/01/2008 2 commentaires

Il y a quelques semaines, ma très chère compagne m’a pressé pour que nous fassions l’acquisition d’une de ces merveille technologique de l’électroménager qui me font douter de l’avenir de l’usage des mains de notre humanité modernisée : une machine à pain. En solde.

Le principe est simple : on remplit une petite cuve en inox avec différents ingrédients dans un certain ordre (comme de l’eau, du beurre, du sucre, du sel, de la farine et de la levure), on choisi une programme concordant avec notre recette, et la machine s’occupe de tout : elle pétri la pâte de son petit bras mécanique, longuement, elle la laisse reposer et gonfler dans un environnement moite et chaud, puis elle la cuit en faisant rougir son petit corps de chauffe.

Sur le papier, c’est génial : on peut même la programmer pour avoir du pain chaud au réveil. Dans la réalité, je pense que je dois être le cuisinier le plus naze de toute l’histoire de la machine à pain. Sur mes nombreux essais (avec différentes farines, différents temps de cuisson, et même un sachet de farine « toute prête avec déjà la levure spécialement pour votre machine à pain que même un manchot pourrait réussir »), j’en reviens toujours au même point : le pain en forme de brique, à la couleur de brique, et surtout, à la densité d’une brique.

Imaginez un cube (et encore, c’est beaucoup dire, 10cm sur 10 de base (c’est la forme de la cuve), et 6 ou 7cm de haut, 12cm dans les meilleurs jours), brun foncé, la croute comme une muraille de Chine acérée de piques, la mie comme un annuaire téléphonique édition Île-de-France. Pour mieux visualiser, ce soir, j’ai failli à la recommandation de toute mère à son enfant lorsqu’il se munit d’un couteau à pain : Fait attention à ne pas te couper !. Et je me suis ouvert le puce. Avec le pain. Un morceau de croute particulièrement aiguisé s’est plantée dans mon doigt jusqu’au sang.

Bref, je crois que le dépôt du tablier s’impose. Mais pas avant d’avoir rentabilisé cette démoniaque machine et son packaging à base d‘inratable et de sans échec, non mais. Je suis peut-être un loser de la baguette, un vaincu de la miche, mais tant pis. Allez, salut.

Categories: Hors sujet Tags: ,