header fails parsing htmlspecialchars

I'm making a search engine which has some extra inputfields (order by, searching for name and/or searching for the text)

see the $_GET array:
f is an array, this array will be changed by the function below to f=n|i|b
s isn't changed
o isn't changed
q is the query <-- this is where the problem is!

the address: http://recepten/?act=search&f%5Bn%5D=true&f%5Bi%5D=true&f%5Bb%5D=true&s=n&o=asc&q=%26
$_GET: Array ( [act] => search [f] => Array ( [n] => true [i] => true [b] => true ) [s] => n [o] => asc [q] => & )

$_GET["q"] = addslashes(htmlentities($_GET["q"]));
if (is_array($_GET["f"])) {
      foreach ($_GET["f"] as $key => $value) {
            $_GET["f"][] = $key;
            unset($_GET["f"][$key]);
      }
      $_GET["f"] = implode("|", $_GET["f"]);
      foreach ($_GET as $key => $value) {
            if ($key != "act") {
                  $href .= "&".$key."=".$value;
            }
      }
      $href = '?act=search'.$href;
      header("Location: ".$href);
      exit();
}

after this function the $_GET array should be: Array ( [act] => search [f] => n|i|b [s] => n [o] => asc [q] => & )
and the address: http://recepten/?act=search&f=n|i|b&s=n&o=asc&q=%26

but,

the address is this: http://recepten/?act=search&f=n|i|b&s=n&o=asc&q=&amp; <-- the %26 is changed to &amp;
it seems quite logical, but I must keep the %26 or else you know what will happen when someone searches for something like &act=something

before the header is send, $href is (already) ?act=search&f=n|i|b&s=n&o=asc&q=&amp;

how can I make it so that the %26 isn't changed to &amp;?
LVL 1
nemesis3884Asked:
Who is Participating?
 
moduloConnect With a Mentor Commented:
Closed, 500 points refunded.

modulo
Community Support Moderator
Experts Exchange
0
 
crackyCommented:
Have you tried removing the htmlentities() function from your code?

It is this that's converting %26 to &.

Since the string you get in the page is already URL encoded, there is no need to encode it with htmlentities() at all.

If you really want to use htmlentities(), just call html_entitity_decode() when outputting the string again like so:

$_GET["q"] = addslashes(htmlentities($_GET["q"]));
if (is_array($_GET["f"])) {
     foreach ($_GET["f"] as $key => $value) {
          $_GET["f"][] = $key;
          unset($_GET["f"][$key]);
     }
     $_GET["f"] = implode("|", $_GET["f"]);
     foreach ($_GET as $key => $value) {
          if ($key != "act") {
               $href .= "&".$key."=".$value;
          }
     }
     $href = '?act=search'.html_entitity_decode($href);
     header("Location: ".$href);
     exit();
}

Bear in mind that people can still manipulate your querystring whether you like it or not, so make sure you don't let the querystring have a lot of impact on your script, or people will soon work out how to play with it.
0
 
nemesis3884Author Commented:
both the things you mentioned didn't work, but I think i've found the solution

I'm now using urlencode:

unset($_GET["order"]);
if (is_array($_GET["f"])) {
      foreach ($_GET["f"] as $key => $value) {
            $_GET["f"][] = $key;
            unset($_GET["f"][$key]);
      }
      $_GET["f"] = implode("|", $_GET["f"]);
      foreach ($_GET as $key => $value) {
            if ($key != "act") {
                  if ($key == "q") {
                        $value = urlencode(stripslashes($value));
                  }
                  $href .= "&".$key."=".$value;
            }
      }
      $href = '?act=search'.$href;
      header("Location: ".$href);
      exit();
}

this seems to be working, off course I also use htmlspecialchars to keep the html-like input away ;)
0
 
skullnobrainsCommented:
<just a note>
if you need something near to secure, the FIRST character to strip is '|' so you of course had better not using it yourself. you may even manage to fool your own code with a bit of rotten luck.

what is the point of having a temporary page ? couldn't you perform the search on the same page, and then both html and messy redirects with headers won't be an issue ?
</note>
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.