Forum CMS Made Simple FR

Version complète : [Résolu][FormBuilder] é commercial mal restitué dans un input text
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Citation :#~~~~~ DEBUT BLOC A NE PAS SUPPRIMER ~~~~~
#~ Version du CMS: #1.10.3
#~ Url du site :
#~ Hébergeur / Soft :
#~ Informations Système : FormBuilder 0.7.2
#~~~~~ FIN BLOC A NE PAS SUPPRIMER ~~~~~



Bonjour,

En recherchant la méthode utilisée par FormBuilder pour initialiser un input text avec un "&", je constate qu'il retourne &. Donc si j'écris "Moi & co", en cas d'erreur dans le formulaire, FormBuilder me retourne "Moi & co".

Je n'ai pas trouvé ce cas dans les bugs du module.

Cela dit, ce n'est visiblement pas un problème directement lié à FormBuilder car j'utilise de mon côté directement l'API de CMSMS.

Donc voici ma question : avez-vous également ce problème, et si oui, comment l'avez-vous résolu ?

Cela fait un paquet d'heures que j'épluche google et le code source de quelques modules, j'avoue commencer à sécher...

D'avance merci !

Heriquet
Salut Eric,
il doit y avoir un htmlentities pour des raisons de sécurité!
Puisque tu utilise l'API, tu dois pouvoir coller un html_entity_decode au bon endroit?
see: http://php.net/manual/fr/function.html-e...decode.php
En effet, j'en utilise un.

J'ai récupéré une fonction dans FormBuilder :

Code :
[== PHP ==]
    function unmy_htmlentities($val)
    {
        if ($val == "")
        {
            return "";
        }
        $val = html_entity_decode($val);
        $val = str_replace("&","&",$val);
        $val = str_replace("<!--","<!--",$val);
        $val = str_replace("-->","-->",$val);
        $val = str_replace("&gt;",">", $val);
        $val = str_replace("&lt;","<",$val);
        $val = str_replace("&quot;","\"",$val);
        $val = str_replace("$","\$",$val);
        $val = str_replace("!","!",$val);
        $val = str_replace("'","'",$val);
        
        // Uncomment if you need to convert unicode chars
        return $val;
    }

... que j'appelle dans la création du champ.

Code :
[== PHP ==]
$this->CreateInputTextWithLabel($id, 'FirstName', isset($params['FirstName'])?$this->unmy_htmlentities($params['FirstName']):'', 40, 80, '', $this->Lang('contact_firstname'))

Et malgré cela, rien à faire, pour les apostrophes, j'obtiens le bon résultat en utilisant cette fonction.
c'est pas plutôt à la restitution du champ qu'il faudrait appliquer cette fonction?
En fait si on regarde l'API,

Code :
[== PHP ==]
/**
* @access private
*/
function cms_module_CreateInputTextWithLabel(&$modinstance, $id, $name, $value='', $size='10', $maxlength='255', $addttext='', $label='', $labeladdtext='')
{
  $id = cms_htmlentities($id);
  $name = cms_htmlentities($name);
  $value = cms_htmlentities($value);
  $size = cms_htmlentities($size);
  $maxlength = cms_htmlentities($maxlength);

        if ($label == '') {
      $label = $name;
    }
    $text = '<label class="cms_label" for="'.$id.$name.'" '.$labeladdtext.'>'.$label.'</label>'."\n";
    $text .= $modinstance->CreateInputText($id, $name, $value, $size, $maxlength, $addttext);
    $text .= "\n";
    return $text;
}


function cms_htmlentities($string, $param=ENT_QUOTES, $charset="UTF-8", $convert_single_quotes = false)
{
    $result = "";
    #$result = htmlentities($string, $param, $charset);
    $result = my_htmlentities($string, $convert_single_quotes);
    return $result;
}

/**
* A replacement for the built in htmlentities method.
*
* @ignore
* @param string  input string
* @param boolean A flag wether or not to handle single quotes.
* @return unknown
*/
function my_htmlentities($val, $convert_single_quotes = false)
{
    if ($val == "")
    {
        return "";
    }
    $val = str_replace( " ", " ", $val );

    //Remove sneaky spaces
    // $val = str_replace( chr(0xCA), "", $val );

    $val = str_replace( "&"            , "&amp;"         , $val );
    $val = str_replace( "<!--"         , "<!--"  , $val );
    $val = str_replace( "-->"          , "-->"       , $val );
    $val = preg_replace( "/<script/i"  , "<script"   , $val );
    $val = str_replace( ">"            , "&gt;"          , $val );
    $val = str_replace( "<"            , "&lt;"          , $val );


    $val = str_replace( "\""           , "&quot;"        , $val );

    // Uncomment it if you need to convert literal newlines
    //$val = preg_replace( "/\n/"        , "<br>"          , $val );

    $val = preg_replace( "/\\$/"      , "$"        , $val );

    // Uncomment it if you need to remove literal carriage returns
    //$val = preg_replace( "/\r/"        , ""              , $val );

    $val = str_replace( "!"            , "!"         , $val );
    $val = str_replace( "'"            , "'"         , $val );

    // Uncomment if you need to convert unicode chars
    //$val = preg_replace("/&#([0-9]+);/s", "&#\1;", $val );

    // Strip slashes if not already done so.

    //if ( get_magic_quotes_gpc() )
    //{
    //    $val = stripslashes($val);
    //}

    if ($convert_single_quotes)
    {
        $val = str_replace("\\'", "&apos;", $val);
        $val = str_replace("'", "&apos;", $val);
    }

    // Swop user inputted backslashes

    //$val = preg_replace( "/\(?!&#|?#)/", "\", $val );

    return $val;
}

On constate ceci :

Code :
[== PHP ==]
$val = str_replace( "&", "&amp;", $val );

Le problème se situerait dès lors dans l'API ? Je ne vois pas bien ce que je peux faire pour contourner le problème, si ce n'est de ne pas utiliser la méthode de l'API ?

Ca s'apparente à un bug ca non ?
non, pour moi ça n'est pas un bug. C'est une sécurité.
Je ne comprends pas bien ton problème. Si en entrée il y a une conversion, il faut qu'à la sortie tu fasses l'inverse.
Donc, j'en reviens à ce que je disais plus haut : il faut utiliser html_entity_decode, ou bien si c'est pour de l'affichage, le navigateur traduit parfaitement ces codes (ils ont même été fait pour ça!).
Citation : Donc si j'écris "Moi & co"
Note Perso : c'est une super bêtise de mettre ce symbole dans une page WEB le & est un caractère réservé
C'est du même niveau que les espaces ou les accents dans les noms de fichier Big Grin
@jce, je suis d'accord avec toi, mais l'utilisateur lambda ne sait pas forcément qu'il ne peut pas utiliser & dans un input text.

@jissey, le texte est restitué dans un input text donc les entités ne sont pas interprétées. &amp; devient &amp;amp; sauf s'il est affiché hors d'une zone de sélection.
ha ok, et $this->unmy_htmlentities($params['FirstName']) ne rempli pas son oeuvre?
Citation :mais l'utilisateur lambda
heu je ne suis pas sur mais l'initiateur du post n'est "l'utilisateur lambda" :lol:
jissey a écrit :ha ok, et $this->unmy_htmlentities($params['FirstName']) ne rempli pas son oeuvre?

Si tout à fait, mais lorsque je passe la valeur de retour de cette fonction, elle est placée directement dans l'appel de CreateInputTextWithLabel, qui appelle à son tour cms_module_CreateInputTextWithLabel, qui appelle cms_htmlentities qui appelle my_htmlentities.

Or, my_htmlentities remplace les & par des &amp;.

Ou alors j'ai loupé quelque chose !
ha! ca y est, jai compris.
Et si tu passes unmy_htmlentities($params['FirstName']) dans smarty plustôt que par creatinput, tu pourras l'utiliser dans ton gabarit (si tu en as un).

<edit> en plus pas besoin d'utilser unmy_htmlentities puisque les entités html seront interprétées par le navigateur </edit>
Bon j'ai un peu d'infos complémentaire :

Code :
[== PHP ==]
En mettant des traces dans modform.inc.php,

/**
* @access private
*/
function cms_module_CreateInputTextWithLabel(&$modinstance, $id, $name, $value='', $size='10', $maxlength='255', $addttext='', $label='', $labeladdtext='')
{
    if(strpos($value, 'Eric') === 0)
    {
        echo '<br/>cms_module_CreateInputTextWithLabel : '.$value.' '.strlen($value).'<br/>';
    }

  $id = cms_htmlentities($id);
  $name = cms_htmlentities($name);
  $value = cms_htmlentities($value);
  $size = cms_htmlentities($size);
  $maxlength = cms_htmlentities($maxlength);

    if(strpos($value, 'Eric') === 0)
    {
        echo '<br/>cms_module_CreateInputTextWithLabel : '.$value.' '.strlen($value).'<br/>';
    }
        if ($label == '') {
      $label = $name;
    }
    $text = '<label class="cms_label" for="'.$id.$name.'" '.$labeladdtext.'>'.$label.'</label>'."\n";
    $text .= $modinstance->CreateInputText($id, $name, $value, $size, $maxlength, $addttext);
    $text .= "\n";
    return $text;
}

J'ai l'output suivant, en écrivant "Eric J&J" dans le textbox.

cms_module_CreateInputTextWithLabel : Eric J&J 8

cms_module_CreateInputTextWithLabel : Eric J&J 12

Ce qui confirme qu'on ne sait rien faire et que c'est à ce moment que ma valeur est modifiée...
et tu n'as pas la possibilité de passer ta variable php en variable smarty et de l'utiliser sans passer par createinputtext, comme je te l'ai suggéré plus haut?
Ah si bien sur... mais ca perd un peu de son intérêt... c'est moins bien quoi.

Cela dit, le problème ne se pose que quand on utilise ce symbole ET qu'on s'est trompé dans le captcha.

Y a peu de chances que ca se produise même si on ne peut pas exclure la possibilité.
<humour>
Ha! toi si je ne te connaissais pas, je t'enverrais chez plumeau! Smile
2 jours que j'essaie de comprendre ton problème et constate avec toi qu'on ne peut pas le résoudre sans modifier le core...je te trouve une solution de contournement et c'est tout ce que tu trouves à dire!
Citation :Ah si bien sur... mais ca perd un peu de son intérêt... c'est moins bien quoi.
D'autres auraient dit : ha!!! tu me sauve la vie ou bien : Hoo! merci, je n'y avais pas pensé! ou encore : vous êtes vraiment super sur ce forum, tiens, je vais faire un don!
Et bien non, M Heriquet (futur papa) ne se départit pas de son flegme belge. Smile

Bah! tant pis, il faut savoir rester humble, courber l'échine et avancer...allons les gars! en avant!
</humour>

Bon, ben moi avec tout ça, j'ai plus d'idée mon copain :p

ps: je mets les balises <humour> parce qu'une fois, mes divagations ont mal été interprétées.
Héhé tracasse, on a de l'humour nous en Belgique !

Un grand merci pour tes réponses et ton temps mon ami.

En fait j'aurais gagné du temps en passant par Smarty directement, sans faire un détour sur le forum, mais s'agissant du développement d'un module, je tenais absolument à passer par l'API de CMSMS et avoir une "vraie bonne solution" et pas un workaround.

J'ai laissé le code tel quel. Il aurait été sans doutes possible de faire un str_replace sur l'output de la méthode CreateInputTextWithLabel mais est-ce que cela aurait été plus propre ? Je ne pense pas.

Et modifier le core, non merci. C'est encore pire !

Conclusion pour ceux qui auraient le même souci : le "problème" existe tant dans FormBuilder que dans le core lui-même...

LA solution serait peut-être de réécrire la méthode qui génère les input text et de ne pas remplacer les &...
je pense au final qu'il est normal de transformer les entités html c'est une bonne partie de sécurité et on peut ainsi utiliser l'API en toute tranquillité.
C'est ce que je faisais avant que je découvre CMSMS et que je codais à la mimine! Il faut même enlever les retours chariots encore plus dangereux dans le cas d'un mail (je n'ai jamais vérifié tiens!).
Bon, ben on ferme hein?
Tiens nous au courant de la parenthèse que j'ai ouverte plus haut Wink
Ok ok !

Pour la parenthèse, toujours RAS... c'est prévu pour ce lundi en théorie mais elle semble bien se plaire avec sa maman Smile !

J'en profite pour liquider des petites tâches qui traînent dans mes cartons...