Bonjour, Sincèrement je n'ai pas tout lu (vraiment beaucoup trop long, tu pourrais proposer un résumé de tes mails en introduction ;) ). Mon dépôt osmose sur gitorious n'est pas vraiment une référence. Regardes plutôt la branche dev de http://gitorious.org/osmose pour la version de développement.
Frédéric Le 10 février 2012 11:51, Philippe Verdy <verd...@wanadoo.fr> a écrit : > Je viens de trouver un bogue dans Osmose, sur son serveur Backend. > > ==== Premier problème (le plus sérieux) === > > Cela se situe ici: > > https://gitorious.org/~frodrigo/osmose/frodrigo-osmose-backend/blobs/master/modules/OsmSax.py > > Aux deux lignes suivantes du module SaxWriter lorsqu'il génère le code > des valeurs d'attributs des élements XML : > > 369 self._write(' %s=%s' % (name, quoteattr(value))) > 378 self._write(' %s=%s' % (name, quoteattr(value))) > > En effet, la fonction Python quoteattr() ne représente pas > correctement le caractère "&" qu'il laisse sous cette forme, alors > qu'il FAUT le réencoder sous la forme "&" > > La fonction quoteattr() est importée depuis le module Python > "sax.saxutils", absent dans les sources GIT d'Osmose. C'est elle qui > est ici en cause. > > Cela affecte la modification des éléments contenant un caractère "&" > dans leur valeur (par exemple les relations contenant un tag "url", ou > certains tags "name" parfaitement valides). > > L'effet de ce bogue est que le XML reçu par le client et éditable par > "rawedit" est invalide, et ne peut pas être revalidé tel quel ! > Sinon on reçoit un message affiché en rouge en haut de l'écran > rawedit: "XML parser can't parse this data", et les données ne sont > pas enregistrées. > > Pour contourner le problème, il faut soit même corriger le code XML > qui a été reçu en remplaçant les "&" affichés dans l'éditeur dans les > valeurs de tags par "&" avant de valider, même si on n'a pas > réellement touché à la valeur. > > Le risque subsiste que même sans y toucher, l'absence de modification > manuelle pour faire la correction risque parfois d'être acceptés comme > du XML valide (par exemple quand un "&" littéral est suivi de > quelquechose qui ressemble à une référence numérique de caractère ou > une référene d'entité XML définie dans le schéma XML utilisé), ce qui > corrompra les données qui n'avaient pas lieu d'être modifiées. > > Je ne sais pas si c'est la fonction quoteattr() du module sax.saxutils > qui devrait être corrigée, ou si une autre fonction devrait plutôt > être définie ou utilisée ici, ou si un paramètre supplémentaire > optionnel de quoteattr() permet de préciser la conformité avec XML > (car quoteattr() n'est pas obligé de remplacer ces "&" si la fonction > est utilisée pour générer du HTML ou du SGML): dans ce cas il faut > passer ce paramètre oublié. > > A ce sujet, quoteattr() recode toutes les apostrophes ASCII (') sous > la forme ' alors que c'est inutile (et peu lisible) ici, étant > donné que la chaine retournée sera encadrée de guillemets doubles > ASCII ("). En revanche les quatre caractères suivants doivent être mis > sous forme de référence à une des quatre seules entité de caractères > XML prédéfinie : > > - les guillemets doubles ASCII (") sous la forme " > - le signe inférieur (<) sous la forme < > - le signe supérieur (>) sous la forme > > - le signe et commercial (&) sous la forme & > > Et c'est tout ! Tout le reste peut (et devrait) rester sous leur forme > littérale (même l'apostrophe ici, bien que XML prédéfinisse aussi une > cinquième entité "'" puisque la syntaxe XML permet aussi aux > valeurs d'attributs d'être encadrées par des apostrophes ASCII au lieu > de guillemets ASCII). > > > ==== Deuxième problème (lié au premier) === > > Enfin je note que le code Javascript envoyé au client utilise le > constructeur: new XMLHttpRequest(), mais sans préciser le jeu de > caractères qui sera utilisé pour dialoguer avec le serveur : > > function ApiDo(action) > { > var myReq = new XMLHttpRequest(); > if (myReq) { > myReq.onreadystatechange = function (evnt) { if(myReq.readyState == 4) { > res = myReq.responseText.split('\n'); > document.getElementById('osm_msg').innerHTML = res[0]; > tmp = res.shift(); > document.getElementById('osm_data').value = res.join('\n'); > } } > myReq.open('POST', '/' + action + '/' + osm_type + '/' + osm_id, true); > myReq.setRequestHeader("Content-type", > "application/x-www-form-urlencoded"); > poststr = "osm_data=" + > encodeURIComponent(document.getElementById("osm_data").value ); > myReq.send(poststr); > } > } > > Rien n'oblige actuellement le navigateur à supposer que cette requête > se fera en codage UTF-8, même si la page web et le code javascript > sont eux-même codés en UTF-8. Dans les faits, cette requête telle > qu'elle est envoyée au serveur ne précise rien du tout, ce qui demande > alors que les données incluses dans la valeur "osm_data=" ne soient > que de l'ASCII pur. > > Ici le problème est que pour s'assurer que ce sera uniquement de > l'ASCII, ce javascript utilise encodeURIComponent(), dont le > comportement dépend du navigateur : la source est bien de l'UTF-16, > son résultat sera bien de l'ASCII compatible avec une syntaxe de > composant URI, mais asolument rien n'indique dans quel jeu de > caractères se fera la conversion de la chaine source UTF-16 vers un > jeu restreint à 8 bits (avant ensuite de convertir les espaces ASCII > sous la forme "+", et les octets non ASCII et non imprimables ou > réservés par la syntaxe des URI sous la forme "%nn"). > > En effet, le constructeur XMLHttpRequest crée un nouveau document > totalement séparé du document source (hormi son domaine de sécurité) > et communique même avec un serveur backend distinct du serveur > frontend affichant la carte Osmose et l'interface d'édition. Il n'y a > strictement rien dans le code qui indique que le backend utilise > UTF-8, et cela pourrait expliquer pourquoi la base OSM contient > maintenant des caractères mal réencodés (il suffit par exemple qu'un > utilisateur utilise un navigateur configuré tel que UTF-8 n'est pas > son codage par défaut, mais utilise par défaut ISO-8859-1, > Windows-1252 voire aussi Mac-Roman). > > Il faudrait donc que le javascript précise bien le codage utilisé > avant de les mettre dans les données qu'il envoie en POST-Data dans la > valeur "osmdata", sous forme URL-encodée (même si la requête ici > indique au serveur que les données sont supposées bien être au format > "application/x-www-form-urlencoded", cela ne dispense pas le > javascript de coder correctement sour cette forme). > > Ce problème existe même avec les navigateurs récents, pour peu que > l'utilisateur n'a pas configuré son navigateur pour utiliser UTF-8 > comme codage par défaut, et selon d'autres réglages possibles de la > façon d'interpréter les URI présentes dans de vieilles pages HTML non > conformes XML/XHTML ni HTML5. > > Il n'est pas inintéressant de lire la doc officielle de la norme > ECMAScript au sujet des mises en garde sur l'effet et la compatibilité > de la fonction encodeURIComponent(), dès lors que la chaîne source en > paramètre ne contient PAS UNIQUEMENT des caractères ASCII mais > n'importe quel autre "caractère" > > > === Note 1 : question de compatiblité des chaines en Javascript/ECMAScript === > > Note : les "caractères" en Javascript, ceux qu'on énumère dans une > chaine avec la méthode .charAt(n), ou qu'on compte avec la méthode > .length(), ne sont PAS les caractères au sens Unicode, mais seulement > des "unités de code" arbitraires sur 16 bits. > > Javascript n'oblige même pas en fait à ce que ses chaines soit > nécessairement codées de façon interne en UTF-16, car ce pourrait > aussi bien être un codage JIS sur 16 bits, voire n'importe quelle > valeur binaire non textuelle, comme aussi en Java : il est > parfaitement valide en Javascript d'insérer des codets nuls dans ces > "chaines" ou un codet égal à 0xFFFF, qui ne correspond à rien de > valide en UTF-16, ou encode d'y mettre un codet égal à 0xD800 isolé > non suivi d'un codet entre 0xDC00 et DFFF, là encore invalide en > UTF-16, et les chaines Javascript font la distinction entre différents > codages de sauts de lignes. Javascript initialement n'obligeait même > pas à ce que son codage interne soit avec des unités de code sur au > moins 16 bits (ce n'est plus le cas depuis la norme ECMAScript qui > précise bien que ces unités de code DOIVENT être sur 16 bits, mais > n'oblige toujours pas à ce que ce soit uniquement de l'UTF-16 valide). > > Bref attention à la fonction encodeURIComponent(string) ! Lire à ce > sujet ce qui a été fait dans jQuery pour résoudre ce problème de > compatibilité entre navigateurs et selon leur configuration: je > suggère donc d'utiliser jQuery dans le frontend, car il résoud bien > des difficultés, et fournit une bibliothèque standard pour effectuer > des requêtes XML fiables avec un serveur backend. > > > === Note 2 : XMLHTtpRequest, et suggestion pour la sécurité === > > D'ailleurs le constructeur XMLHtppRequest() a aussi des problèmes de > sécurité répertoriés, comme aussi des problèmes mieux connus de > compatiblité avec différents types de navigateurs. > > jQuery fournit une solution stable et sure, et même les organismes de > surveillance de la sécurité sur le web recommandent de ne plus > l'utiliser du tout et de passer aux requêtes JSON dès que possible car > elles incluent une implémentation native avec des contraintes bien > plus forte de sécurité (qui évitent par exemple des attaques de type > "XSS", Cross-Site Scripting, ou des attaques directement sur la > plateforme native du navigateur client, surtout avec les vieilles > versions d'Internet Explorer où XMLHttpRequest n'existait que par un > composant externe ActiveX). > > _______________________________________________ > Talk-fr mailing list > Talk-fr@openstreetmap.org > http://lists.openstreetmap.org/listinfo/talk-fr _______________________________________________ Talk-fr mailing list Talk-fr@openstreetmap.org http://lists.openstreetmap.org/listinfo/talk-fr