Solved

Validate against carriage returns in a textarea

Posted on 2016-10-04
22
27 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
Comment Utility
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
Comment Utility
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 51

Expert Comment

by:Julian Hansen
Comment Utility
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
 
LVL 3

Author Comment

by:colinspurs
Comment Utility
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
Comment Utility
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 51

Expert Comment

by:Julian Hansen
Comment Utility
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
Comment Utility
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 51

Expert Comment

by:Julian Hansen
Comment Utility
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
Comment Utility
@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 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 70 total points
Comment Utility
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
Comment Utility
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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
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 51

Expert Comment

by:Julian Hansen
Comment Utility
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
Comment Utility
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
Comment Utility
What does this do

Works correctly, results as expected.
0
 
LVL 3

Author Comment

by:colinspurs
Comment Utility
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
Comment Utility
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 51

Accepted Solution

by:
Julian Hansen earned 290 total points
Comment Utility
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 51

Expert Comment

by:Julian Hansen
Comment Utility
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
Comment Utility
Move the escape_string to after the check for validity

That's it!

Many thanks all.
0
 
LVL 3

Author Closing Comment

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

Expert Comment

by:Julian Hansen
Comment Utility
You are welcome.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

728 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now