Caractères nulles dans un NSPipe ?
tablier
Membre
J'utilise NSTask et NSPipe pour lancer un "AppleEvent Logging" et récupérer le texte de retour.
Jusque là rien d'exceptionnel! pour faire cela, j'ai utilisé "TaskWrapper" qui est dans l'exemple "Moriarity" de Apple.
Mais "AppleEvent Logging" à quelques bugs!! Utilisé directement dans la console j'obtiens (extrait du texte):
Le code '? devrait être '?'. Mais comme ces codes ont tous 4 caractères, je soupçonne que celui-ci devrait s'écrire
'?\000\000\000', soit ? suivi de 3 nulls (c'est parfaitement autorisé dans les codes AppleEvent).
Mon problème:
en utilisant "AppleEvent Logging" lancé par un NSTask et en récupérant les données par un NSPipe, le bloc de donnée qui contient les nuls est carrément sauté!
Je n'arrive pas à savoir si c'est le pipe qui me fait une m.... ou si c'est le traitement postérieur dans "TaskWrapper" qui est inadéquat.
Qui aurait des lumières sur un truc aussi tordu? est-ce que le Pipe transmet tout les caractères y compris les nuls?
(Je joins le texte complet pris dans la console dans un .rtf zippé. Le bloc sauté est en rouge!)
Jusque là rien d'exceptionnel! pour faire cela, j'ai utilisé "TaskWrapper" qui est dans l'exemple "Moriarity" de Apple.
Mais "AppleEvent Logging" à quelques bugs!! Utilisé directement dans la console j'obtiens (extrait du texte):
key 'fltp' -
{ 1 } 'enum': 4 bytes {
'?
}
key '----' -
{ 1 } 'obj ': - 4 items {
key 'form' -
{ 1 } 'enum': 4 bytes {
'indx'
Le code '? devrait être '?'. Mais comme ces codes ont tous 4 caractères, je soupçonne que celui-ci devrait s'écrire
'?\000\000\000', soit ? suivi de 3 nulls (c'est parfaitement autorisé dans les codes AppleEvent).
Mon problème:
en utilisant "AppleEvent Logging" lancé par un NSTask et en récupérant les données par un NSPipe, le bloc de donnée qui contient les nuls est carrément sauté!
Je n'arrive pas à savoir si c'est le pipe qui me fait une m.... ou si c'est le traitement postérieur dans "TaskWrapper" qui est inadéquat.
Qui aurait des lumières sur un truc aussi tordu? est-ce que le Pipe transmet tout les caractères y compris les nuls?
(Je joins le texte complet pris dans la console dans un .rtf zippé. Le bloc sauté est en rouge!)
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En effet, tu dois déjà savoir que mettre entre appostrophes un caractère, comme [tt]'A'[/tt], est la façon de représenter le caractère "A" en C, et est strictement équivalente à écrire son code ascii. Ainsi, les notation 'A', 0x41 et 65 sont toutes les trois équivalentes, elles représentent un char (valeur sur un octet) de valeur 65.
Eh bien avec deux caractères entre les apostrophes, c'est pareil sauf que ça représente un "short". Et avec quatre caractères, un long. Ainsi, 'AB' sera équivalent à 0x4142 (ou 0x4241 je sais plus trop ça dépend de l'endianness attention à ce point tout de même), et 'ABCD' à 0x41424344 (ou 0x44434241 ?).
Du coup un code AppleEvent, généralement représentés par 4 lettres entre apostrophes, est en fait un long... et '?', qui correspond à la valeur 63, peut tout à fait tenir dans un long
J'ai posté chez apple pour leur signaler l'erreur "unmatched apostrophe". Mais d'ici qu'ils acceptent de corriger l'erreur !!!!!
Ce qui m'intéresse c'est: est ce qu'il y a moyen de s'en sortir en récupérant réellement tout les caractères, y compris les nulls?
Pour info voici le texte de base envoyé à Apple:
Débugguer avec des outils buggués ! ou va-t-on! Dans ce cas précis, les AppleEvents sont corrects car le script marche bien! je pense donc que c'est seulement l'affichage qui est faux (printf?). Mon idée serait d'avoir un "Pipe binaire" qui permettrait de récupèrer tout les caractères! mais je ne sais pas comment faire!
Bien sur, dans "AEv-Utility" je tiens compte de ces erreurs! Mais à chaque découverte d'erreur je dois corriger le programme!!
1) D'une c'est pas une application de debug, mais un flag pour activer ou non des traces. Et ça ça change tout. Tu peux pas dire que des traces sont buguées, c'est juste des traces.
C'est comme si tu disais que les messages de la console sont bugués parce qu'ils affichent "Laoding" au lieu de "Loading" pour un message de debug écrit par une appli juste parce que le dev qui a mis ces messages de debug a fait une faute de frappe...
2) C'est aussi pour ça que je te rappelle que c'est pas non plus fait pour être parsé ce genre de sortie. Rien n'interdit à Apple d'ailleurs un jour de faire sortir comme traces autre chose que cela, par exemple mettre un ">>" au début de chaque ligne qu'il écrit... C'est comme la console, c'est fait pour être lu par un utilisateur pour l'aider à déboguer, mais pas à être parsé par un outil.
Après si tu fais un outil qui arrive à parser ça, tu as le droit, mais comme la sortie des traces de debug n'est pas non plus faite pour ça, donc tu ne pourras pas non plus te plaindre si Apple change ses traces.
D'ailleurs, dans les documents officiels documentant ces méthodes de debug et traces, c'est même dit très clairement...
Donc certes je comprend que ça soit vraiment gênant pour toi et que ça t'énerve. Mais en même temps c'est pas un bug d'un logiciel dont on cause, là . C'est une trace qui n'est pas formatée comme tu espérais parce qu'ils ont oublié un cas particulier en utilisant un fprintf pour écrire une trace dans la console... on peut pas vrament parler de bug.
La manière d'utiliser le "Apple Event logging" est expliquée dans "Apple Events Programming Guide", dans la section "Examining Apple Events". Donc de ce coté tu as tout a fait raison, cela peut être considéré comme du "trace".
Par contre Apple dit clairement que cela permet d'examiner le contenu des Apple Events. Il définit les syntaxes de représentation, mais ne s'y tient pas! dans ce sens la on peut aussi dire qu'il y a un bug dans le programme de 'trace' et que les résultats sont à considérer avec suspicion! Ainsi, si tu veux reproduire l'Apple Event en question, tu ne peux savoir comment est fait le code '? Le 0x00 est un caractère signifiant dans les codes puisque en fait un code est un long, donc '? (si le fprintf s'est arrêté au caractère nul) correspond au moins à 256*256 possibilités: de '?\000\000\000' à '?\000\777\777'
Nous ne nous fâcherons pas pour cela et je vais faire un appel au peuple car je suis incapable de faire seul un très grand nombre d'essais avec AEv-Utility. je demanderai juste qu'on me renvoie les scripts qui posent problème (pas de résultat ou résultats tronqués). Je vais voir comment présenter cela dans les projets d'applications je pense.
Ex de buffer overflow :
Ex correct :
Donc si tu lui demande d'afficher une chaine '?\000\000\000' sous la forme :
printf stoppera sont exécution au premier 0x00 et la dernière apostrophe ne sera jamais affiché car le caratère de fin de chaine est avant la fin réel de la chaine.
Il faut donc utiliser un autre caractère !
Je connais ça depuis les années 90/92. Si tu as suivi la discussion, tu as du voir que ce n'est pas moi qui utilise Printf, mais le système sous le terminal (bash probablement). Donc je ne peux rien y changer! J'ai donc signalé à Apple le fait que le code était tracé incomplètement (unmatched apostrophe), ce qui ne m'empèche pas de ne pas en être content!!!!
Bug certainement généré par un printf qui ne prend pas en compte que le code à 4 caractères peut contenir des caractères NULL, enfin on suppose que ça vient de là même si rien nous le prouve... Mais c'est justement parce qu'on sait comment fonctionne printf qu'on a supposé que la raison venait de là !!
Ceci dit quand j'y pense, vu que le FourCC* est en fait un long, je trouverai bizarre qu'ils utilisent un [tt]printf("%s",...)[/tt], mais y'a tellement de manières pour afficher ce genre de choses... Par exemple définir Et utiliser byte[0] à byte[3] pour afficher les caractères avec un printf("%c%c%c%c",...)
Ou encore utiliser directement quoique là ça affiche le code dans le sens inverse (du moins sous Intel), donc faut passer fourcc à la moulinette du swap des octets selon l'endianness...
Ou encore ils ont peut-être une méthode interne qui prend un FourCC (sous forme de long) et génère un char[5] à partir de là , donc le 5e char est \0 bien sûr...
Dans tous les cas, tout cela n'est que supposition de comment Apple a généré ces traces... Mais vu ce qu'on voit, à mon avis dès que ton FourCC contient un caractère non-imprimable (enfin soit un long dont un des octet de sa représentation informatique ait une valeur inférieure à 20, quoi), c'est pas gagné qu'ils aient prévu le coup pour l'afficher proprement !
*FourCC est le terme générique pour désigner ce genre de code à 4 caractères, qu'Apple a souvent utilisé, y compris pour les codes types et créateur. C'est l'acronyme de "Four Characters Code".
Ce que je voulais dire c'est que si il utilise printf tu risque pas de pouvoir afficher des caractères non imprimables. Sauf en hexa !