Solved

Validate against carriage returns in a textarea

Posted on 2016-10-04
22
33 Views
Last Modified: 2016-10-04
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

0
Comment
Question by:colinspurs
  • 8
  • 7
  • 3
  • +2
22 Comments
 
LVL 22

Assisted Solution

by:Ferruccio Accalai
Ferruccio Accalai earned 70 total points
ID: 41827915
Why don't you check if $temp is == ""?

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

Open in new window

1
 
LVL 9

Assisted Solution

by:Brian Tao
Brian Tao earned 70 total points
ID: 41827965
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
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41827969
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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 3

Author Comment

by:colinspurs
ID: 41828027
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
 
LVL 9

Expert Comment

by:Brian Tao
ID: 41828049
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
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41828099
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
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 41828116
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
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41828127
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
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 41828136
@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
 
LVL 109

Assisted Solution

by:Ray Paseur
Ray Paseur earned 70 total points
ID: 41828138
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
 
LVL 3

Author Comment

by:colinspurs
ID: 41828163
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
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41828211
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
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41828217
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
 
LVL 3

Author Comment

by:colinspurs
ID: 41828241
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
 
LVL 3

Author Comment

by:colinspurs
ID: 41828254
What does this do

Works correctly, results as expected.
0
 
LVL 3

Author Comment

by:colinspurs
ID: 41828281
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
 
LVL 9

Expert Comment

by:Brian Tao
ID: 41828292
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
 
LVL 55

Accepted Solution

by:
Julian Hansen earned 290 total points
ID: 41828309
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
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41828323
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
 
LVL 3

Author Comment

by:colinspurs
ID: 41828334
Move the escape_string to after the check for validity

That's it!

Many thanks all.
0
 
LVL 3

Author Closing Comment

by:colinspurs
ID: 41828350
Thanks for your time and help everyone.  I should give the whole story next time, I was trying to simplify for convenience.
0
 
LVL 55

Expert Comment

by:Julian Hansen
ID: 41828357
You are welcome.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Things That Drive Us Nuts Have you noticed the use of the reCaptcha feature at EE and other web sites?  It wants you to read and retype something that looks like this.Insanity!  It's not EE's fault - that's just the way reCaptcha works.  But it is …
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question