0

So I wrote this function:

function validate_text($text,$min,$max,$include_spaces=true)
{
    $match = array();
    $regex = ($include_spaces)?"/[a-zA-Z0-9 .\-_]":"/[a-zA-Z0-9.\-_]";
    if($max<=0)
    {
        $regex = sprintf($regex."{%d,}/",$min);
    }
    else
    {
        $regex = sprintf($regex."{%d,%d}/",$min,$max);
    }
    if($include_spaces)
    {
        preg_match($regex,$text,$match);
    }
    else
    {
        preg_match($regex,$text,$match);
    }
    return (implode($match)==$text);
}

and use it as such:

  (validate_text($_POST['prod_name'],10,100,true)

and I can't get it to validate the simple title "painting by cbkirby" I just need it to make sure no wacky characters that wouldn't otherwise show up in a product title (like simecolons or quotes '",etc) won't make it into the mysql. What am I doing wrong?

jason dancks
  • 1,152
  • 3
  • 9
  • 29
  • 1
    What exactly is the set of inputs you are looking to match with this regular expression? – murgatroid99 Dec 06 '12 at 02:43
  • 1
    Also, what is the point of the last conditional? It seems to do the same thing whether `$include_spaces` is true or false. – murgatroid99 Dec 06 '12 at 02:48
  • 1
    Your regex works, you probably have some unexpected characters in your input because replacing `$_POST['prod_name']` with `'painting by cbkirby'` returns `true`. – jeroen Dec 06 '12 at 02:59
  • @murgatroid I know I've been debuggin code and got impatient and just wanted to eliminate possible errors. – jason dancks Dec 06 '12 at 03:08
  • Also, the $Include_spaces, as you can guess, was supposed to let me know if spaces where OK, like in a name. I thought the 2 regexes would work different with a space in [] brackets? – jason dancks Dec 06 '12 at 18:16

1 Answers1

1

I'm not sure why you do all this, when you could just say "if this pattern matches" and anchor the pattern at both ends. preg_match already tells you whether the pattern matched; all you have to do is tell it to try and match the whole string. :)

function validate_text($text,$min,$max,$include_spaces=true)
{
    $chars = ($include_spaces) ? "[a-zA-Z0-9 .\-_]" : "[a-zA-Z0-9.\-_]";
    if ($max <= 0) $max = '';
    $regex = "/^{$chars}{{$min},{$max}}$/";
    return !!preg_match($regex, $text);
}

As for your original function, though, long-winded though it might be, it seems to work. You might want to var_dump($_POST['prod_name']) to make sure it's what you think it is. (Keep in mind if prod_name is in the query string, you're going to find it in $_GET rather than $_POST.)


Now...as for the goal...

If you're doing this to keep "bad" chars out of the SQL, that's a bit misguided. It's entirely conceivable for a name to have an apostrophe in it, for example. I've seldom been more annoyed at a site than when i take the time to enter a bunch of data and i get some "sorry, your data is invalid" message even though it's correct. :P "This common and perfectly legitimate character is invalid" sounds to me like "our site's not handling data properly".

Personally, unless i have a good business reason to limit the data, i don't. Keeping the SQL clean is not a business reason, as it's not at all difficult to keep things safe...

$db = new mysqli('localhost', 'dbusername', 'dbpassword', 'dbname');
$stmt = $db->prepare("
    INSERT INTO products (prod_title, other_stuff)
    VALUES (?, ?)
");
$stmt->bind_param('ss', $_POST['prod_title'], $_POST['other_stuff']);
$stmt->execute();

At this point, i really don't even have to care what prod_title and other_stuff contain. When you use placeholders and bind params this way, mysqli keeps the SQL and data separate, so it's impossible* to break stuff. Whatever's in there will make it into the database just fine. You can do pretty much the same thing for updates and deletes, and just slightly different for select queries.

* In some very obscure circumstances, it's possible to break. But you basically have to have a perfect storm of really bad circumstances, including ancient versions of MySQL and character sets no one outside of China uses.

cHao
  • 84,970
  • 20
  • 145
  • 172
  • Well I'm dealing with php4 so no parameterized queries. Do you think then maybe base encoding, where I simply have function left shift and right-shift the characters? There is still the problem of People can make up categories for their products. Unless I simply remove that feature and only new categories can be made by me... I'll go that route I think. – jason dancks Dec 06 '12 at 05:57
  • Eh. What incompetent still runs live servers with PHP4? It's been obsolete for a decade. :P Oh well. Even without PHP5, there's still `mysql_real_escape_string`... Normally i'd all but order people to get away from any function with `mysql_` in the name, but considering you're just banging rocks together over there anyway...it's about as good as you're gonna get. – cHao Dec 06 '12 at 06:24