Welcome Guest, Not a member yet? Register   Sign In
form_prep appears to be broken in 1.7.2 html entities are no longer protected. Or was it broken before?
#11

[eluser]rip_pit[/eluser]
[quote author="darrenm" date="1265932448"]
As a workaround, I've introduced a new function:

Code:
function fix_form_prep($str) {

    $find = array('&','"',''',''','&gt','&lt');
    $replace = array('&','"',''',''','>', '<');

    return str_replace($find,$replace,$str);

}

I then call this after the offending htmlspecialchars in form_prep
Code:
$str = htmlspecialchars($str);
$str = fix_form_prep($str);

This is working, but it lack elegance for me - there must be a better way?

NOTE: the encoding on this forum has scrambled the above function a bit, but you should get the idea.[/quote]

i found a little bug in that function,
line : ,''','&gt','&lt'
should be : ,''','>','<'

I also had to add a new key, ''', without the leading zero, to be converted.

here's the function including these fixes :
Code:
function fix_form_prep($str) {

    $find = array('&','"',''',''','>','<',''');
    $replace = array('&','"',''',''','>', '<',''');

    return str_replace($find,$replace,$str);

}
#12

[eluser]kenjis[/eluser]
I think 1.7.2's code is better than 1.7.1. Because I think to store encoded data is wrong.

But isn't it better that form_prep() has a option parameter "double_encode" same as htmlspecialchars() ?
http://php.net/function.htmlspecialchars
#13

[eluser]Whit Nelson[/eluser]
Thanks rip_pit, that fixed it. I sure don't like tweakin' the core tho. Tongue
#14

[eluser]jodeck[/eluser]
Had the same problem. Fixed it by commenting out the "prepped_fields" static array:

Code:
if ( ! function_exists('form_prep'))
{
    function form_prep($str = '', $field_name = '')
    {
        #static $prepped_fields = array();
        
        // if the field name is an array we do this recursively
        if (is_array($str))
        {
            foreach ($str as $key => $val)
            {
                $str[$key] = form_prep($val);
            }

            return $str;
        }

        if ($str === '')
        {
            return '';
        }

        // we've already prepped a field with this name
        // @todo need to figure out a way to namespace this so
        // that we know the *exact* field and not just one with
        // the same name
        #if (isset($prepped_fields[$field_name]))
        #{
        #    return $str;
        #}
        
        $str = htmlspecialchars($str);

        // In case htmlspecialchars misses these.
        $str = str_replace(array("'", '"'), array("'", """), $str);

        #if ($field_name != '')
        #{
        #    $prepped_fields[$field_name] = $str;
        #}
        
        return $str;
    }
}

Is working for me. I was having a problem when posting input arrays from HTML forms, ie name="$user_name[]" and the like.
#15

[eluser]spaceball[/eluser]
This was like a super pain for fix. I was looking at why my single quotes were being escaped into HTML chars and not a simple \'
but eh. okay long story short. I just decided to replace the function form_prep() with the CI version 1.7.1

If any one is worried about hacking the code just create a file title "MY_form_helper.php" in /application/helpers



Code:
<?php

/**
* Form Prep from version CI 1.7.1. Overide 1.7.1 form_prep.
* /application/helpers/MY_form_helper.php
*
*/
function form_prep($str = '')
{
    // if the field name is an array we do this recursively
    if (is_array($str))
    {
        foreach ($str as $key => $val)
        {
            $str[$key] = form_prep($val);
        }
        
        return $str;
    }
    
    if ($str === '')
    {
        return '';
    }
    
    $temp = '__TEMP_AMPERSANDS__';
    
    // Replace entities to temporary markers so that
    // htmlspecialchars won't mess them up
    $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
    $str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);
    
    $str = htmlspecialchars($str);
    
    // In case htmlspecialchars misses these.
    $str = str_replace(array("'", '"'), array("'", """), $str);
    
    // Decode the temp markers back to entities
    $str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
    $str = preg_replace("/$temp(\w+);/","&\\1;",$str);
    
    return $str;
}
#16

[eluser]Unknown[/eluser]
if you look at the form_prep function, it is actually calling the set_value function of the form validation object, which returns the value untouched.

so whenever i want to store a value into the database, i will call that function directly instead of the global set_value function. too bad this isn't documented properly.

$data->field = $this->form_validation->set_value('field');
#17

[eluser]EvilivE[/eluser]
What worked for me was to "extended" form_helper with MY_form_helper and rewrote set_value. I don't like to messing around with system files when I can alter in application files.

Code:
/**
* Form Value
*
* Grabs a value from the POST array for the specified field so you can
* re-populate an input field or textarea.  If Form Validation
* is active it retrieves the info from the validation class
*
* @access    public
* @param    string
* @return    mixed
*/
if ( ! function_exists('set_value'))
{
    function set_value($field = '', $default = '')
    {
        if (FALSE === ($OBJ =& _get_validation_object()))
        {
            if ( ! isset($_POST[$field]))
            {
                return $default;
            }

            return $_POST[$field];
        }

        return $OBJ->set_value($field, $default);
    }
}




Theme © iAndrew 2016 - Forum software by © MyBB