Validate against carriage returns in a textarea

Hi experts,

I have a textarea in a form.  I validate that this should not be empty, i.e. it must have some visible input.

I can break the validation simply by hitting the Enter key, thus putting a carriage return in an apparently blank field, will be accepted as valid.

How do I get around this?

My current code:
$temp = trim($_POST[$fields[$key]['form_name']]);  // Translates to eg. $temp = trim($_POST['txtBookTitle'])  
	
if (empty($temp) )
{
	$error_array[] = $fields[$key]['message'];
	${$key} = '';
}

Open in new window

LVL 3
colinspursAsked:
Who is Participating?
 
Julian HansenConnect With a Mentor Commented:
What does this do
$_POST[$fields[$key]['form_name']] = mysqli_real_escape_string($db, $_POST[$fields[$key]['form_name']]);

Open in new window

Do a dump of the output from that - what do you get on 2 carriage returns
'\r\n\r\n

This is the escaped version of the 2 carriage returns - which won't match on the trim or the preg.
Move the escape_string to after the check for validity
1
 
Ferruccio AccalaiConnect With a Mentor Senior developer, analyst and customer assistance Commented:
Why don't you check if $temp is == ""?

if ($temp == "" )
{
	$error_array[] = $fields[$key]['message'];
	${$key} = '';
}

Open in new window

1
 
Brian TaoConnect With a Mentor Senior Business Solutions ConsultantCommented:
You don't have to get around it.  In the PHP you're using trim(), which already removes the carriage return from the string.
2
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
Julian HansenCommented:
This does two things
1. Ensures that $_POST[$field...] contains only characters you expect (santisizes)
2. Makes sure that what is in the field matches what you expect (checks input valid)

$temp = isset($_POST[$fields[$key]['form_name']]) 
   ? preg_match('/\w+/', $_POST[$fields[$key]['form_name']]) 
   : false;

if ($temp)  {
   echo "Input is valid";
}
else {
   echo "input is invalid";
}

Open in new window

1
 
colinspursAuthor Commented:
Thanks guys.

In all 3 cases, only putting carriage returns in passes the validation, whereas simple spaces doesn't.

This is on my PC (xampp) so I can't show an example.
0
 
Brian TaoSenior Business Solutions ConsultantCommented:
Cannot help then.
Please make sure that your $fields[$key]['form_name'] does translate to the name of the textarea.
And maybe attach your both HTML and the PHP script here.  Maybe it's not the validation itself, but some code later than that.

Good luck!
1
 
Julian HansenCommented:
I put the code above into a sample here. The sample demonstrates the code works.

HTML
    <form action="t1660.php" method="post">
		<textarea name="test"></textarea> <input type="submit" />
	</form>

Open in new window

PHP
<pre>
<?php
print_r($_POST);
$temp = isset($_POST['test']) 
   ? preg_match('/\w+/', $_POST['test']) 
   : false;

if ($temp) {
echo "ok";
} 
else {
echo "not ok";
}?>
</pre>

Open in new window

1
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
Another try (this should remove any new line even if it's empty)
$temp = trim(preg_replace('/\s+/', '', $_POST[$fields[$key]['form_name']]));  	
if ($temp == "")
{
	$error_array[] = $fields[$key]['message'];
	${$key} = '';
}

Open in new window

0
 
Julian HansenCommented:
The problem with removing white space is instead of

This is my required response 

Open in new window


You get
Thisismyrequiredresponse

Open in new window


Not necessarily the desired outcome
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
@Not necessarily the desired outcome
Maybe that's why he's assigning it to a $temp variable just to check for validation.
I guess he uses a non trimmed $_POST value once validated.
0
 
Ray PaseurConnect With a Mentor Commented:
I would think that a carriage-return line-feed sequence inside  the input should probably be preserved.  PHP trim() is likely to be your friend.  This little demonstration script can help you see what your code is doing to the characters that are entered in the textarea.
https://iconoun.com/demo/temp_colinspurs.php
<?php // demo/temp_colinspurs.php
/**
 * https://www.experts-exchange.com/questions/28974158/Validate-against-carriage-returns-in-a-textarea.html
 *
 * http://php.net/manual/en/function.trim.php
 */
ini_set('display_errors', TRUE);
error_reporting(E_ALL);

// INITIAL DEFAULT VALUE
$txt = NULL;

if (!empty($_POST['txt']))
{
    // TRIM WHITESPACE FROM THE ENDS OF THE TEXTAREA
    $txt = $_POST['txt'];
    $txt = trim($txt);

    // DISPLAY THE ORIGINAL CONTENTS
    echo '<pre>';
    hexdump($_POST['txt']);
    echo '</pre>';
    echo PHP_EOL;

    // DISPLAY THE TRIMMED CONTENTS
    echo '<pre>';
    hexdump($txt);
    echo '</pre>';
    echo PHP_EOL;
}

// CREATE A FORM TO ACQUIRE THE TEXTAREA
$form = <<<EOD
<form method="post">
<textarea name="txt">$txt</textarea>
<input type="submit" />
</form>
EOD;

echo $form;


// UTILITY FUNCTION TO SHOW US THE HEX BYTE VALUES
function hexdump($str, $br=PHP_EOL)
{
    if (empty($str)) return FALSE;

    // GET THE HEX BYTE VALUES IN A STRING
    $hex = str_split(implode(NULL, unpack('H*', $str)));

    // ALLOCATE BYTES INTO HI AND LO NIBBLES
    $hi  = NULL;
    $lo  = NULL;
    $mod = 0;
    foreach ($hex as $nib)
    {
        $mod++;
        $mod = $mod % 2;
        if ($mod)
        {
            $hi .= $nib;
        }
        else
        {
            $lo .= $nib;
        }
    }

    // SHOW THE SCALE, THE STRING AND THE HEX
    $num = substr('1...5...10...15...20...25...30...35...40...45...50...55...60...65...70...75...80...85...90...95..100..105..110..115..120..125..130', 0, strlen($str));
    echo $br . $num;
    echo $br . $str;
    echo $br . $hi;
    echo $br . $lo;
    echo $br;
}

Open in new window

1
 
colinspursAuthor Commented:
Yeah there's something funny going on here.

I've done my own simplified test script and testing for empty($temp)  and Julian's preg_match both work, though testing for $temp == '' following the trim() allows a blank textarea through.

I feel bad about using everyone's time on this, so let me get back to the original code and I'll try to see what's going on.

Cheers

<?php
if (isset($_POST['btnSubmit']))
{
	$temp = trim($_POST['btnSubmit']);  
	
	if ($temp == '')
	{
	   echo "Input is invalid";
	}
	else 
	{
	   echo "input is valid";
	}
	exit();
	// Allows anything through - all blanks are valid.
	
	
	/*if (empty($temp))
	{
	   echo "Input is valid";
	}
	else 
	{
	   echo "input is invalid";
	}
	exit();*/
	// Works - line breaks only are not valid
	
	
	/*$temp = isset($_POST['txtBody']) 
	   ? preg_match('/\w+/', $_POST['txtBody']) 
	   : false;
	
	if ($temp)  {
	   echo "Input is valid";
	}
	else {
	   echo "input is invalid";
	}
	exit();*/
	// Works - line breaks only are not valid
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
	<div id="maintenance_form" > 
    <form name="form1" id="form1" action="" method="post" enctype="multipart/form-data" >
        <fieldset> 
                <label for="txtBody" class="item_label">Body:</label>
                <textarea rows="4" cols="75" name="txtBody" maxlength="1000" ></textarea>
                <input type="submit" name="btnSubmit" id="btnSubmit" value="Save"  />
	            <input type="submit" name="btnCancel" id="btnCancel" value="Cancel"  />
		</fieldset>
    </form>
    </div> 
</body>
</html>

Open in new window

0
 
Julian HansenCommented:
if (isset($_POST['btnSubmit']))

Open in new window

Why are you testing btnSubmit when your textarea name is txtBody
<textarea rows="4" cols="75" name="txtBody" maxlength="1000" ></textarea>

Open in new window

1
 
Julian HansenCommented:
What does this do
<?php
if (isset($_POST['txtBody']))
{
	$temp = trim($_POST['txtBody']);  
	
	if ($temp == '')
	{
	   echo "Input is invalid";
	}
	else 
	{
	   echo "input is valid";
	}
	exit();
	// Allows anything through - all blanks are valid.
	
	
	/*if (empty($temp))
	{
	   echo "Input is valid";
	}
	else 
	{
	   echo "input is invalid";
	}
	exit();*/
	// Works - line breaks only are not valid
	
	
	/*$temp = isset($_POST['txtBody']) 
	   ? preg_match('/\w+/', $_POST['txtBody']) 
	   : false;
	
	if ($temp)  {
	   echo "Input is valid";
	}
	else {
	   echo "input is invalid";
	}
	exit();*/
	// Works - line breaks only are not valid
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
	<div id="maintenance_form" > 
    <form name="form1" id="form1" action="" method="post" enctype="multipart/form-data" >
        <fieldset> 
                <label for="txtBody" class="item_label">Body:</label>
                <textarea rows="4" cols="75" name="txtBody" maxlength="1000" ></textarea>
                <input type="submit" name="btnSubmit" id="btnSubmit" value="Save"  />
	            <input type="submit" name="btnCancel" id="btnCancel" value="Cancel"  />
		</fieldset>
    </form>
    </div> 
</body>
</html>

Open in new window

Seems to work in this sample
0
 
colinspursAuthor Commented:
Trimming the button instead of the textarea - D'OH!

I now trim the textarea and test for it and all solutions work in my test.  I get input is valid 3 times if I just put white space in there.

<?php
if (isset($_POST['btnSubmit']))
{
	$temp = trim($_POST['txtBody']);  
	
	echo "temp == ''<br/>";
	if ($temp == '')
	{
	   echo "Input is invalid<br/>";
	}
	else 
	{
	   echo "input is valid<br/>";
	}
	// Works - line breaks only are not valid
	
	echo "empty(temp)<br/>";
	if (empty($temp))
	{
	   echo "Input is invalid<br/>";
	}
	else 
	{
	   echo "input is valid<br/>";
	}
	// Works - line breaks only are not valid
	
	echo "preg_match<br/>";
	$temp = isset($_POST['txtBody']) 
	   ? preg_match('/\w+/', $_POST['txtBody']) 
	   : false;
	
	if ($temp)  {
	   echo "Input is valid";
	}
	else {
	   echo "input is invalid";
	}
	exit();
	// Works - line breaks only are not valid
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
	<div id="maintenance_form" > 
    <form name="form1" id="form1" action="" method="post" enctype="multipart/form-data" >
        <fieldset> 
                <label for="txtBody" class="item_label">Body:</label>
                <textarea rows="4" cols="75" name="txtBody" maxlength="1000" ></textarea>
                <input type="submit" name="btnSubmit" id="btnSubmit" value="Save"  />
	            <input type="submit" name="btnCancel" id="btnCancel" value="Cancel"  />
		</fieldset>
    </form>
    </div> 
</body>
</html>

Open in new window

0
 
colinspursAuthor Commented:
What does this do

Works correctly, results as expected.
0
 
colinspursAuthor Commented:
This is my actual original code wherein lies the problem.
foreach ($fields as $key => $value)
	{
		if (isset($_POST[$fields[$key]['form_name']]))
		{
			$_POST[$fields[$key]['form_name']] = mysqli_real_escape_string($db->connection, $_POST[$fields[$key]['form_name']]);
			
			$temp = trim($_POST[$fields[$key]['form_name']]);  // Translates to eg. $temp = trim($_POST['txtBookTitle'])  
	
			if ($fields[$key]['required'] == 1)
			{
				$temp = isset($_POST[$fields[$key]['form_name']]) 
				   ? preg_match('/\w+/', $_POST[$fields[$key]['form_name']]) 
				   : false;
				
				if ($temp)  {
				   echo "Input is valid";
				}
				else {
				   echo "input is invalid";
				}
				exit();
			}

			/*if (empty($temp) && $fields[$key]['required'] == 1)
			{
				$error_array[] = $fields[$key]['message'];
				${$key} = '';
			}*/
		}
	}

Open in new window

The $fields array has these contents:
Array
(
    [body] => Array
        (
            [required] => 1
            [default_value] => 
            [form_name] => txtBody
            [type] => text
            [message] => Body must be entered
            [db_tablename] => pp_jobs
        )

    [pos_id] => Array
        (
            [required] => 0
            [default_value] => 0
            [form_name] => txtPosId
            [type] => text
            [message] => 
            [db_tablename] => pp_jobs
        )

    [stored_file_name] => Array
        (
            [required] => 0
            [default_value] => 
            [form_name] => txtStoredFileName
            [type] => text
            [message] => 
            [db_tablename] => pp_jobs
        )

    [type] => Array
        (
            [required] => 0
            [default_value] => 
            [form_name] => txtType
            [type] => text
            [message] => 
            [db_tablename] => pp_jobs
        )

)

Open in new window

0
 
Brian TaoSenior Business Solutions ConsultantCommented:
So in my comment #a41828049 I said "Please make sure that your $fields[$key]['form_name'] does translate to the name of the textarea."
Were you really checking against another field which is not the textarea?
0
 
Julian HansenCommented:
Updated code
foreach ($fields as $key => $value) {
	if (isset($_POST[$fields[$key]['form_name']]))
	{
		
		$temp = trim($_POST[$fields[$key]['form_name']]);  // Translates to eg. $temp = trim($_POST['txtBookTitle'])  

		if ($fields[$key]['required'] == 1)
		{
			$temp = isset($_POST[$fields[$key]['form_name']]) 
			   ? preg_match('/\w+/', $_POST[$fields[$key]['form_name']]) 
			   : false;
			
			if ($temp)  {
			   echo "Input is valid";
			}
			else {
			   echo "input is invalid";
			}
			exit();
		}

		/*if (empty($temp) && $fields[$key]['required'] == 1)
		{
			$error_array[] = $fields[$key]['message'];
			${$key} = '';
		}*/
	}
}

Open in new window

Use real_escape_string just before you enter the data into the database.
0
 
colinspursAuthor Commented:
Move the escape_string to after the check for validity

That's it!

Many thanks all.
0
 
colinspursAuthor Commented:
Thanks for your time and help everyone.  I should give the whole story next time, I was trying to simplify for convenience.
0
 
Julian HansenCommented:
You are welcome.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.