developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#998 closed bug (wontfix)

jIniFileModifer et les contenus avec des "

Reported by: foxmask Owned by:
Priority: low Milestone: Jelix 1.1.4
Component: jelix:utils Version: 1.1.3
Severity: minor Keywords:
Cc: Blocked By:
Blocking: Documentation needed: no
Hosting Provider: Php version:

Description

Quand on saisi des apostrophes doubles dans un textarea (par exemple), le contenu est bien sauvegardé dans le fichier concerné mais est tronqué à l'affichage :

 rules="voici mes \"regles\""

mais à l'affichage on obtient plus que :

 voici mes

Change History (17)

comment:1 Changed 11 years ago by foxmask

la regexp de la fonction parse est fausse :

 } else if(preg_match('/^\s*([a-z0-9_.-]+)(\[([a-z0-9_.-]*)\])?\s*=\s*(")?([^"]*)(")?(\s*)/i', $line, $m)) {

en fait il faut permettre

 rules="coucou"

et

 rules="coucou le bel\"oiseau\""

comment:2 Changed 11 years ago by foxmask

  • Milestone set to Jelix 1.1.4

comment:3 Changed 11 years ago by foxmask

CheckPoint? :

ligne 56 :

à la place de

 if(preg_match('/^(.*)"\s*$/', $line, $m)) {
  $currentValue[2].=$m[1];
  $multiline=false;
  $this->content[$currentSection][]=$currentValue;
 } else {
   $currentValue[2].=$m[1]."\n";
 }

il faut

 if(preg_match('/^(.*)"\s*$/', $line, $m)) {
  $currentValue[2].=$m[1];
  $multiline=false;
  $this->content[$currentSection][]=$currentValue;
 } else {
   $currentValue[2].=$line."\n";
 }

car evidement si la regexp ne correspond pas à la fin d'un paramètre entouré d'un " ; on est sur une ligne "sans rien" donc on la concatène telle quelle.

je regarde à présent le pb avec le " dans la value.

comment:4 Changed 11 years ago by foxmask

cette ligne

 } else if(preg_match('/^\s*([a-z0-9_.-]+)(\[([a-z0-9_.-]*)\])?\s*=\s*(")?([^"]*)(")?(\s*)/i', $line, $m)) {

ne permet pas cle="valeur1 \"valeur2\"" on est tronqué à

 valeur1

cette ligne

 if(preg_match('/^(.*)"\s*$/', $line, $m)) {

ne permet pas

 line1
 line2
 \"line3\"
 line4

ici on est tronqué à

 line1
 line2
 "line3

comment:5 Changed 11 years ago by foxmask

Donc à la place de

  if(preg_match('/^(.*)"\s*$/', $line, $m)) {

il faudrait

  if(preg_match('/^"*(.*)"\s*$/', $line, $m)) {

et ce cas fonctionnerait

mais cette fois ci, ceci ne marche pas

 line1
 "line2"
 "line3"
 "line4"

comment:6 Changed 11 years ago by foxmask

je ne trouve pas de moyen de gerer cela à part suivre la voix de php.net avec la fonction parse_ini_file qui shoot les " de ses valeurs

comment:7 Changed 11 years ago by foxmask

je serai pour que les valeurs sur plusieurs lignes soient sous la même forme que dans le defaultconfig.ini.php comme ici :

emailHeaders="Content-Type: text/plain; charset=UTF-8\nFrom: webmaster@yoursite.com\nX-Mailer: Jelix\nX-Priority: 1 (Highest)\n"

on remplacerait les chr(10) chr(13) par \n dans le texte, non ?

comment:8 Changed 11 years ago by foxmask

dans jIniFileModifier ceci fonctionne parfaitement, ca evite les " dans les value et les retours à la ligne sont remplacés par des \n. Ce qui permet tout comme dans tout fichier ini de php, d'avoir la valeur sur une seule ligne.

    public function setValue($name, $value, $section=0, $key=null) {
        $value = str_replace(chr(13).chr(10),"\\n",$value);
        $value = str_replace('"',"",$value);
}
....
    public function getValue($name, $section=0, $key=null) {
...
   return str_replace('\n',chr(13).chr(10),$item[2]); // au lieu de return $item[2];
}

et ca marche impecablement !

comment:9 Changed 11 years ago by laurentj

  • Priority changed from normal to low
  • Severity changed from normal to minor

Je n'ai pas trop suivi ces commentaires. Une remarque cependant : il faut verifier que \" est bien prise en compte tel qu'on l'attend, quand on parse le fichier ini avec parse_ini_file par exemple, ou d'autres outils qui fonctionnent correctement.

En d'autres termes, se renseigner sur le format ini.

Conçernant les \n : pas de traitement spécifique. là encore, vérifier la spec du format ini. il ne me semble pas que parse_ini_file traite les chaines "\n".

comment:10 Changed 11 years ago by foxmask

en tout cas jIniFileModifier ne sait pas gerer le multiligne avec des " ;)

on est tronqué au premier ".

reste à trouver une solution.

comment:11 follow-up: Changed 11 years ago by laurentj

j'ai fait des tests.

On oublie donc le support de "\n" : pas interprété par parse_ini_file. Notez que si vous mettez la valeur sur plusieurs lignes, entre double quote, ça sera récupéré correctement (en tout cas avec ma version de php 5.2.6)

cle="ma
valeur"

à ce sujet, vérifier que jIniFileModifier sait lire ce genre de valeur. Il me semble que oui. vérifier les tests unitaires.

Pour ce qui est du \", parse_ini_file réagit bizarrement :

quietMessage="Sorr""y man." => on obtient 'Sorry man'
quietMessage="Sorr\"y man." => on obtient 'Sorr\y man'
quietMessage="Sorr"y man." => on obtient 'Sorry man'

Donc effectivement, je propose qu'on prenne en compte les " qui sont au milieu d'une chaine. En fait, prendre toute la chaine qui suit le =, et retirer le " initial et final (et prendre en compte donc les vrai sauts de ligne entre les deux)

comment:12 Changed 11 years ago by foxmask

une petite remarque en passant, je trouve dommage de refaire ce que php fait avec parse_ini_file.

ne pourrait-on pas manipuler les values retournées directement pour chaque array grâce à parse_ini_file ?

ainsi on s'affranchi du parsing (multiligne/multiquote) du contenu de la value puisque parse_ini_file s'en charge.

je n'ai la solution toute prête mais comme on parle de parse_ini_file et de pas allourdir le fmrk en réinventant la roue ... ;-)

comment:13 Changed 11 years ago by laurentj

jIniFileModifier ne lit pas tout à fait le fichier ini comme le fait parse_ini_file. Le but de jIniFileModifier, est de pouvoir modifier un fichier ini tout en préservant les lignes vides, les commentaires etc..

Et bien entendu, pour juste lire un fichier ini, il faut utiliser la fonction php, et c'est ce qui est fait ailleurs dans le framework. Mais si on veut modifier le fichier ini tout en préservant les commentaires ou autres, on peut utiliser jIniFileModifier.

comment:14 in reply to: ↑ 11 Changed 11 years ago by foxmask

Replying to laurentj:

Donc effectivement, je propose qu'on prenne en compte les " qui sont au milieu d'une chaine. En fait, prendre toute la chaine qui suit le =, et retirer le " initial et final (et prendre en compte donc les vrai sauts de ligne entre les deux)

dans ton énoncé, retirer le " initial ok mais comment sait on quand une valeur finie avec le " final ?

dans ce qui suit comment savoir quel est le guillemet qui est celui qui "clos" la valeur de macle ?

macle="ligne0
ligne1
"ligne2"
"ligne3"
"

je pourrai dire 'la fin de la valeur de macle se termine quand je rencontre uneautrecle=' mais quand j'ai un fichier avec une seule "macle=" ...

je continue de réfléchir ;)

comment:15 Changed 11 years ago by laurentj

  • Resolution set to wontfix
  • Status changed from new to closed

J'ai réalisé plein de tests avec des cas différents d'usage de quotes dans une valeur, avec parse_ini_file. conclusion: totalement buggé. je n'arrive pas à en retirer un comportement cohérent. Une seule chose dont je sois sûr : parse_ini_file mange tout les ", quels que soit le cas.

Donc même si on supporte le " dans les valeurs, il faudra les "manger", et donc en définitive, il ne sert à rien de mettre des " dans les valeurs.

Donc pas de support des " dans jIniFileModifier. Pas envie de reproduire tout les bugs de parse_ini_file dans cette classe.

comment:16 Changed 11 years ago by foxmask

Dans ces cas la un simple str_replace('"',) dans la valeur doit suffir je regarderai

comment:17 Changed 11 years ago by foxmask

Le plus simple est de faire le str replace lors du $maConfig->setValue() et basta

Note: See TracTickets for help on using tickets.